package org.zfes.snowier.cloud.zbss.asf;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.ImageFormat;

import javax.imageio.ImageIO;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.zfes.snowier.cloud.zbss.asf.biz.dto.ImageInfo;
import org.zfes.snowier.cloud.zbss.asf.biz.factory.FaceEngineFactory;
import org.zfes.snowier.cloud.zbss.asf.biz.util.ImageUtil;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FaceEngineTest2 {
	public static Integer threadPoolSize=8;
	
	public static   String appId = "NDdb9SB4WZHLmPxDVRPCQ5P2MAtghFqsaNarjCUpY5C";
	public static   String sdkKey = "6HgA3YoW7nsdh4F8Mr7vU9bhvyuxTmLbjUpkneTARiQY";
       
    private static ExecutorService executorService;
    
    
    public static void main(String[] args) {
    	FaceEngineTest2 ttt=new FaceEngineTest2(); 
    	ttt.init();
    	ttt.faceEngineTest();
    }
	//特征提取 FaceEngine引擎池
    private GenericObjectPool<FaceEngine> extractFaceObjectPool;
    //人脸对比 FaceEngine引擎池
    private GenericObjectPool<FaceEngine> compareFaceObjectPool;
    
    public  void init() {
        executorService = Executors.newFixedThreadPool(threadPoolSize);
        
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        
        poolConfig.setMaxIdle(threadPoolSize);
        poolConfig.setMaxTotal(threadPoolSize);
        poolConfig.setMinIdle(threadPoolSize);
        poolConfig.setLifo(false);
        
           //特征提取 FaceEngine引擎池
        extractFaceObjectPool= new GenericObjectPool(
        		new FaceEngineFactory(appId, sdkKey, 
        				FunctionConfiguration.builder()
        				.supportFace3dAngle(true)
                		.supportFaceDetect(true)
                		.supportFaceRecognition(true)
                		.supportAge(true)
                		.supportGender(true)
        				.build()), poolConfig);


    }
    



    public void faceEngineTest() {
    	FaceEngine faceEngine = null;
    	try {
    		  faceEngine = extractFaceObjectPool.borrowObject();
    		   String path= "F:/workspace/sts2018/zfes-snowier-cloud-zbss-asf/zfes-snowier-cloud-zbss-asf-router-service/upload/img/sitz/2019/5/12/TiL8PyF85vUC4EoWx5ShDg.jpg";
    			 
    	        ImageInfo imageInfo = ImageUtil.getRGBData(new File(path)).get();
    	        ImageInfo imageInfo2 = ImageUtil.getRGBData(new File(path)).get();
    	        //人脸检测
    	        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
    	        int a=faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
    	        System.out.println("faceEngine.detectFaces-a:"+a);
    	        List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
    	        int b=faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2);
    	        System.out.println("faceEngine.detectFaces-b:"+b);
    	        //提取人脸特征
    	        FaceFeature faceFeature = new FaceFeature();
    	        int c=faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList.get(0), faceFeature);
    	        System.out.println("faceEngine.extractFaceFeature-c:"+c);
    	        faceFeature.getFeatureData();
    	        
    	        FaceFeature faceFeature2 = new FaceFeature();
    	        int d=faceEngine.extractFaceFeature(imageInfo2.getRgbData(), imageInfo2.getWidth(), imageInfo2.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2.get(0), faceFeature2);
    	        System.out.println(faceFeature2.getFeatureData().length);
    	        System.out.println("faceEngine.extractFaceFeature-d:"+d);
    	        //人脸对比
    	        FaceFeature targetFaceFeature = new FaceFeature();
    	        targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
    	       
    	        FaceFeature sourceFaceFeature = new FaceFeature();
    	        sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());

    	        FaceSimilar faceSimilar = new FaceSimilar();
    	        int e=faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
    	        System.out.println(faceSimilar);
    	        System.out.println("faceEngine.compareFaceFeature-e:"+e);
    	        
    	        int processResult = faceEngine.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList, FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).supportLiveness(true).build());
    	        //性别提取
    	        List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
    	        int genderCode = faceEngine.getGender(genderInfoList);
    	        //年龄提取
    	        List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
    	        int ageCode = faceEngine.getAge(ageInfoList);
    	        //3D信息提取
    	        List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
    	        int face3dCode = faceEngine.getFace3DAngle(face3DAngleList);
    	        System.out.println(face3DAngleList);
    	        //活体信息
    	        List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
    	        int livenessCode = faceEngine.getLiveness(livenessInfoList);
    	        livenessInfoList.get(0).getLiveness();
//    	        typedef struct{
//    	    		MInt32*	isLive;			// [out] 判断是否真人， 0：非真人；
//    	    								//						1：真人；
//    	    								//						-1：不确定； 
//    	    								//						-2:传入人脸数>1；
//    	    		MInt32 num;
//    	    }ASF_LivenessInfo, *LPASF_LivenessInfo;
    	        System.out.println(livenessInfoList);
        } catch (Exception e) {
        	e.printStackTrace();
           
        } finally {
            if (faceEngine != null) {
                //释放引擎对象
                extractFaceObjectPool.returnObject(faceEngine);
            }

        }
    	
       

     
    }
    

    public static void base666() {
    	base64StringToImage(s);
    }
    static String s="";
 static void base64StringToImage(String base64String) {
    	try {
    	byte[] bytes1 = Base64.getDecoder().decode(base64String);
    	ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
    	BufferedImage bi1 = ImageIO.read(bais);
    	File f1 = new File("d://out.png");
    	ImageIO.write(bi1, "png", f1);
    	} catch (IOException e) {
    	e.printStackTrace();
    	}
    }
    
    public ImageInfo getRGBData(File file) {
        if (file == null)
            return null;
        ImageInfo imageInfo;
        try {
            //将图片文件加载到内存缓冲区
            BufferedImage image = ImageIO.read(file);
            imageInfo = bufferedImage2ImageInfo(image);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return imageInfo;
    }

    private ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
        ImageInfo imageInfo = new ImageInfo();
        int width = image.getWidth();
        int height = image.getHeight();
        // 使图片居中
        width = width & (~3);
        height = height & (~3);
        imageInfo.setWidth(width);
        imageInfo.setHeight(height);
        //根据原图片信息新建一个图片缓冲区
        BufferedImage resultImage = new BufferedImage(width, height, image.getType());
        //得到原图的rgb像素矩阵
        int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
        //将像素矩阵 绘制到新的图片缓冲区中
        resultImage.setRGB(0, 0, width, height, rgb, 0, width);
        //进行数据格式化为可用数据
        BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
            ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
            colorConvertOp.filter(resultImage, dstImage);
        } else {
            dstImage = resultImage;
        }
        //获取rgb数据
        imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData());
        return imageInfo;
    }


//    class ImageInfo {
//        public byte[] rgbData;
//        public int width;
//        public int height;
//
//        public byte[] getRgbData() {
//            return rgbData;
//        }
//
//        public void setRgbData(byte[] rgbData) {
//            this.rgbData = rgbData;
//        }
//
//        public int getWidth() {
//            return width;
//        }
//
//        public void setWidth(int width) {
//            this.width = width;
//        }
//
//        public int getHeight() {
//            return height;
//        }
//
//        public void setHeight(int height) {
//            this.height = height;
//        }
//    }
}
